﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace personalplaner.business
{
    /// <summary>
    /// Base class for all collections
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionBase<T> : Collection<T>, INotifyPropertyChanged, /*IFocusMover,*/ IDataErrorInfo
    {
        #region IDataErrorInfo Members

        /// <summary>
        /// Gets an error message indicating what is wrong with this object.
        /// </summary>
        /// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
        public string Error { get; private set; }

        /// <summary>
        /// Gets the error message for the property with the given name.
        /// </summary>
        /// <returns>The error message for the property. The default is an empty string ("").</returns>
        public string this[string property]
        {
            get
            {
                string msg = !string.IsNullOrEmpty(property) ? IsPropertyValid(property) : string.Empty;
                if (string.IsNullOrEmpty(msg))
                {
                    this.Error = null;
                }
                else
                {
                    this.Error = property;  //Keep track of the most recently validated property that is invalid.
                }
                return msg;
            }
        }

        /// <summary>
        /// Determines whether the specified property is valid.
        /// </summary>
        /// <param name="property">The name of the property.</param>
        /// <returns>if not valid the error message, otherwise null.</returns>
        protected virtual string IsPropertyValid(string property)
        {
            return null;
        }

        List<string> validateProperties;
        private void FillValidateProperties()
        {

            if (validateProperties != null)
                return;


            //get all properties of the instance (properties of child and base class)
            var properties = (from p in this.GetType().GetProperties()
                              where p.DeclaringType != typeof(ItemBase) && p.Name != "DataValue" && p.Name != "Id"
                              select p).ToList();

            validateProperties = (from ia in properties
                                  orderby ia.Name
                                  select ia.Name).ToList();

            //List<AttributeNameOrder> listItemAttribute = new List<AttributeNameOrder>();
            //var orderPosition = double.MaxValue;

            //foreach (var propertyInfo in properties)
            //{
            //    var customAttributes = propertyInfo.GetCustomAttributes(true).OfType<ItemFocusOrderAttribute>().FirstOrDefault();
            //    if (customAttributes != null)
            //    {
            //        listItemAttribute.Add(new AttributeNameOrder() { Name = propertyInfo.Name, Order = customAttributes.Order });
            //    }
            //    else
            //    {
            //        listItemAttribute.Add(new AttributeNameOrder() { Name = propertyInfo.Name, Order = orderPosition-- });
            //    }
            //}

            //validateProperties = (from ia in listItemAttribute
            //                      where ia.Order > 0.0
            //                      orderby ia.Order
            //                      select ia.Name).ToList();
        }

        /// <summary>
        /// Determines whether this instance is valid.
        /// Properties of this instance (child and base class) will be verified.
        /// </summary>
        /// <param name="validateBase">if set to <c>true</c> validate base values.</param>
        /// <returns>
        ///   <c>true</c> if this instance is valid; otherwise, <c>false</c>.
        /// </returns>
        public bool IsValid
        {
            get
            {
                this.FillValidateProperties();
                if (validateProperties == null)
                {
                    return true;
                }
                else
                {
                    return !validateProperties.Any(prop => !string.IsNullOrEmpty(this[prop]));
                }
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        //#region IFocusMover Members

        //public event EventHandler<MoveFocusEventArgs> MoveFocus;

        //public void RaiseMoveFocus(string focusedProperty)
        //{
        //    if (this.MoveFocus != null)
        //    {
        //        this.MoveFocus(this, new MoveFocusEventArgs(focusedProperty));
        //    }
        //}

        //#endregion

		string _name;
		public virtual string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
				RaisePropertyChanged("Name");
			}
		}

		int _id;
		public virtual int ID
		{
			get
			{
				return _id;
			}
			set
			{
				_id = value;
				RaisePropertyChanged("ID");
			}
		}
    }
}
